package com.xsoft.sms.cmpp20.comm.impl;

import com.xsoft.sms.cmpp20.comm.listener.IClientListener;
import com.xsoft.sms.cmpp20.message.impl.CMPP20Message;
import org.apache.log4j.Logger;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.Executors;

/**
 * package: {PACKAGE_NAME}
 * User: zhanglm
 * Date: 12-9-18
 * Time: 上午11:22
 * Description:
 */
public class CMPP20Client {
	private static Logger logger = Logger.getLogger(CMPP20Client.class);


	public CMPP20Client(String addr, int port, IClientListener cmpp20Comm) {
		socketAddress = new InetSocketAddress(addr, port);
	}

	public boolean connect() {
		channelFactory = new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
		pipelineFactory = new CMPP20ClientPipelineFactory();
		clientBootstrap = new ClientBootstrap(channelFactory);
		clientBootstrap.setPipelineFactory(pipelineFactory);
		clientBootstrap.setOption("tcpNoDelay", true);
		clientBootstrap.setOption("keepAlive", true);

		ChannelFuture future = clientBootstrap.connect(socketAddress);
		if (!future.awaitUninterruptibly().isSuccess()) {
			logger.error("连接短信网关失败");
			clientBootstrap.releaseExternalResources();
			return false;
		}
		clientChannel = future.getChannel();
		return clientChannel.isConnected();
	}

	public void disconnect() {
		if (clientChannel != null && clientChannel.isConnected()) {
			ChannelFuture future =  clientChannel.close();
			future.awaitUninterruptibly();
		}
		if (clientBootstrap != null) {
			clientBootstrap.releaseExternalResources();
		}
		logger.info("断开与短信网关的连接");
	}

	public boolean send(CMPP20Message msg) {
		if (clientChannel.isConnected()) {
			ChannelFuture future = clientChannel.write(msg);
			return future.awaitUninterruptibly().isSuccess();
		}
		return false;
	}

	public boolean isConnected() {
		return clientChannel != null && clientChannel.isConnected();
	}

	private ChannelFactory channelFactory;
	private SocketAddress socketAddress;
	private ClientBootstrap clientBootstrap;
	private ChannelPipelineFactory pipelineFactory;
	private Channel clientChannel;
}
